package com.globalwave.eps.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.globalwave.base.BaseSO;
import com.globalwave.base.BaseServiceImpl;
import com.globalwave.common.ArrayOrderList;
import com.globalwave.common.ArrayPageList;
import com.globalwave.common.C;
import com.globalwave.common.U;
import com.globalwave.common.cache.CodeHelper;
import com.globalwave.common.exception.BusinessException;
import com.globalwave.customer.entity.CustomerProfile;
import com.globalwave.eps.entity.ElectricityProject;
import com.globalwave.eps.entity.ElectricityProjectCriterion;
import com.globalwave.eps.entity.ElectricityProjectLine;
import com.globalwave.eps.entity.ElectricityProjectLineCriterion;
import com.globalwave.system.entity.SessionUser;

@Service("electricityProjectService")
@Scope("prototype")
@Transactional
public class ElectricityProjectServiceImpl 
       extends BaseServiceImpl 
       implements ElectricityProjectService {

	private ElectricityProjectLineService lineBO ;

	@Override
	public ElectricityProject getWithLines(ElectricityProject electricityProject)
			throws Exception {
		
		ElectricityProject project = (ElectricityProject) jdbcDao.get(electricityProject);
		
		project.setLines(getLineBO().queryByProjectId(project.getId())) ;
		
		// get customer
		CustomerProfile criterion = new CustomerProfile() ;
        criterion.setId(project.getCustomer_id()) ;
        
        CustomerProfile customer = (CustomerProfile)jdbcDao.find(criterion) ;
        
        if (customer != null) {
            project.setCustomer_name(customer.getFirst_name()) ;
        }
        
		return project;
	}
	
    public ElectricityProject create(ElectricityProject electricityProject) throws Exception {
    	
    	checkUnified(electricityProject.getApplication_number(), electricityProject.getPid()) ;
    	
    	electricityProject.setCreated_by(SessionUser.get().getLogin_id()) ;
    	electricityProject.setCreated_on(U.currentTimestamp()) ;
    	electricityProject.setStatus_(C.STATUS_ACTIVE) ;
    	if (electricityProject.getCapacitance_amount() == null) {
    	    electricityProject.setCapacitance_amount(C.ZERO_LONG) ;
    	}
    	
    	ElectricityProject project = (ElectricityProject) jdbcDao.insert(electricityProject);
    	
    	saveLines(project) ;
    	/*
    	long i = 0 ;
    	if (electricityProject.getLines() != null) {
	    	for (ElectricityProjectLine line:electricityProject.getLines()) {
	    		line.setProject_id(project.getId());
	    		line.setLine_number(i ++) ;
	    		jdbcDao.create(line);
	    	}
    	}*/
    	
        return project ;
    }

    

    public ElectricityProject copy(ElectricityProject electricityProject) throws Exception {
    	ElectricityProject original = getWithLines(electricityProject) ;
    	
    	original.setId(null) ;
    	original.setName_("Copy Of " + original.getName_()) ;
    	
    	if (original.getName_().length() > 250) {
    		original.setName_(original.getName_().substring(0, 250)) ;
    	}
    	
    	original.setApplication_number(String.valueOf(System.currentTimeMillis())) ;
    	original.setPid(original.getApplication_number()) ;
    	
    	if (original.getLines() != null) {
    		for (ElectricityProjectLine l:original.getLines()) {
    			l.setId(null) ;
    		}
    	}
    	
    	return create(original) ;
    }
    

    public void update(ElectricityProject electricityProject) throws Exception {

    	ElectricityProject old = new ElectricityProject() ;
    	old.setId(electricityProject.getId()) ;
    	old = (ElectricityProject)jdbcDao.find(old) ;
    	
    	String appNumber = electricityProject.getApplication_number() ;
    	String pid = electricityProject.getPid() ;
    	
    	if (old.getApplication_number().equals(appNumber)) {
    		appNumber = null ;
    	}
    	
    	if (old.getPid().equals(pid)) {
    		pid = null ;
    	}
    	
    	checkUnified(appNumber, pid) ;

    	electricityProject.setModified_by(SessionUser.get().getLogin_id()) ;
    	electricityProject.setModified_on(U.currentTimestamp()) ;
    	electricityProject.setStatus_(C.STATUS_ACTIVE) ;
    	if (electricityProject.getCapacitance_amount() == null) {
    	    electricityProject.setCapacitance_amount(C.ZERO_LONG) ;
    	}
    	
    	electricityProject.addExclusions("created_by") ;
    	electricityProject.addExclusions("created_on") ;
    	
        jdbcDao.update(electricityProject) ;

        ElectricityProjectLineCriterion delLine = new ElectricityProjectLineCriterion() ;
        delLine.setProject_id(electricityProject.getId()) ;
        jdbcDao.delete(ElectricityProjectLine.class, delLine) ;
        
    	saveLines(electricityProject);
    }

	private void saveLines(ElectricityProject electricityProject) throws Exception {
		
		long i = 0 ;
		ElectricityProjectLine preview = null ;
    	if (electricityProject.getLines() != null) {
	    	for (ElectricityProjectLine line:electricityProject.getLines()) {
	    		
	    		line.setProject_id(electricityProject.getId());
	    		line.setLine_number(i ++) ;
	    		
	    		if (preview == null) {
	    			line.setBudget_total_diff(C.ZERO_DOUBLE) ;
	    		} else {
	    			double preBudget = preview.getBudget_total() == null ? 0:preview.getBudget_total();
	    			double budget = line.getBudget_total() == null ? 0:line.getBudget_total();
	    			line.setBudget_total_diff(preBudget - budget) ;
	    		}
	    		preview = line ;
	    		
	    		jdbcDao.insert(line);
	    	}
    	}
	}

    public void delete(ElectricityProject electricityProject) throws Exception {
        // delete cascade 
    	ElectricityProjectLineCriterion delLine = new ElectricityProjectLineCriterion() ;
        delLine.setProject_id(electricityProject.getId()) ;
        jdbcDao.delete(ElectricityProjectLine.class, delLine) ;
        
        jdbcDao.delete(electricityProject) ;
        
    }

    public void deleteAll(Long[] ids) throws Exception {
        ElectricityProjectCriterion criterion = new ElectricityProjectCriterion() ;
        criterion.setProject_ids(ids) ;

        jdbcDao.delete(ElectricityProjectLine.class, criterion) ;

        criterion.setProject_ids(null) ;
        criterion.setIds(ids) ;
        
        jdbcDao.delete(ElectricityProject.class, criterion) ;
        
    }

    public ArrayPageList<ElectricityProject> query(
            ElectricityProjectCriterion criterion, 
            int pageIndex, 
            int pageSize, 
            ArrayOrderList orderList) throws Exception {
        
    	BaseSO so = new BaseSO() ;

    	if (orderList == null) {
            so.addAsc("p.id") ;
        } else {
        	so.setOrderList(orderList) ;
        }
        
        so.setPageIndex(pageIndex) ;
        so.setPageSize(pageSize) ;
        
        return (ArrayPageList<ElectricityProject>)jdbcDao.queryName("electricityProjectSQLs:queryProject", so, criterion, ElectricityProject.class) ;
        //return jdbcDao.query(ElectricityProject.class, criterion, orderList, pageIndex, pageSize);
    }


    public ArrayPageList<Object> report(
            ElectricityProjectCriterion criterion, 
            int pageIndex, 
            int pageSize, 
            ArrayOrderList orderList) throws Exception {

    	if (!StringUtils.isEmpty(criterion.getApplication_number())) {
    		criterion.setApplication_number("%" + criterion.getApplication_number() + "%") ;
    	}
    	if (!StringUtils.isEmpty(criterion.getPid())) {
    		criterion.setPid("%" + criterion.getPid() + "%") ;
    	}
    	if (!StringUtils.isEmpty(criterion.getName_())) {
    		criterion.setName_("%" + criterion.getName_() + "%") ;
    	}
    	
    	ArrayPageList<Object> result = 
    		(ArrayPageList<Object>)jdbcDao.queryName("electricityProjectSQLs:projectReport", criterion, HashMap.class) ;
    	
    	for (Object e:result) {
    		Map m = (HashMap) e;
    		m.put("type_name", CodeHelper.getString("EPS.project.type_", "name_", String.valueOf(m.get("type_")))) ;
    		m.put("complete_percentage_name", CodeHelper.getString("EPS.complete.percentage", "name_", String.valueOf(m.get("complete_percentage")))) ;
    		if (m.get("capacitance_amount") != null) {
    		    m.put("capacitance", m.get("capacitance_amount") + CodeHelper.getString("EPS.capacitance_unit", "name_", String.valueOf(m.get("capacitance_unit")))) ;
    		}
    	}
    	
    	return result ;
        //return jdbcDao.query(ElectricityProject.class, criterion, orderList, pageIndex, pageSize);
    }

    private void checkUnified(String application_number, String pid) throws Exception {
    	
    	ElectricityProject project = null ;
    	
    	if (application_number != null) {
    		project = new ElectricityProject() ;
        	project.setApplication_number(application_number) ;

        	project = (ElectricityProject)jdbcDao.find(project) ;

    		if (project != null) {
    			throw new BusinessException("901000") ;//901000', '报装申请编号已经被使用，请重新输入！
    		}
    	}
    	
    	if (pid != null) {
    		project = new ElectricityProject() ;
        	project.setPid(pid) ;

        	project = (ElectricityProject)jdbcDao.find(project) ;

    		if (project != null) {
    			throw new BusinessException("901001") ;//901001', '工程编号已经被使用，请重新输入！
    		}
    	}
    }
    
    
    
	public ElectricityProjectLineService getLineBO() {
		if (lineBO == null) {
			this.lineBO = 
				(ElectricityProjectLineService)CodeHelper.getAppContext().getBean(
						"electricityProjectLineService") ;
		}
		return lineBO;
	}




	public void setLineBO(ElectricityProjectLineService lineBO) {
		this.lineBO = lineBO;
	}

	@Override
	public List<Map<String, Object>> getBudgetStaffOptions() throws Exception {
		return (List<Map<String, Object>>)jdbcDao.queryName("electricityProjectSQLs:getBudgetStaffOptions", null, HashMap.class);
	}


    
}
